pub mod planting;
pub mod player;

use bevy::{color::palettes::css::*, prelude::*, window::WindowCloseRequested};
use planting::{PlantingPlugin, event::ESaveGame};
pub use player::*;

///游戏主插件
pub struct GamePlugin;

impl Plugin for GamePlugin {
    fn build(&self, app: &mut App) {
        app.init_state::<GameState>()
            .add_plugins(PlantingPlugin)
            .add_plugins(PlayerPlugin)
            .add_systems(Startup, spawn_start_menu_ui)
            .add_systems(OnEnter(GameState::LevelLoading), despawn_start_menu_ui)
            .add_systems(OnEnter(GameState::Pause), spawn_start_menu_ui)
            .add_systems(
                Update,
                (btn_click, updata_start_ui)
                    .run_if(in_state(GameState::MainMenu).or(in_state(GameState::Pause))),
            )
            .add_systems(
                Update,
                pause_game.run_if(in_state(GameState::LevelLoading).or(in_state(GameState::Pause))),
            )
            .add_systems(Update, intercept_close_event)
            .add_observer(space_and_enter_event_obs);
    }
}

///开始菜单UI
#[derive(Component)]
struct StartMenuUI;

///开始菜单UI文本
#[derive(Component)]
struct StartMenuUIText {
    pub index: usize,
    pub menu_sub_index: usize,
}

///键盘回车或空格按下事件
#[derive(Event)]
struct ESpaceAndEnterClick;

impl StartMenuUIText {
    pub fn up_indxe(&mut self) {
        if self.index + 1 >= self.menu_sub_index {
            self.index = 0;
        } else {
            self.index += 1;
        }
    }
    pub fn down_indxe(&mut self) {
        if self.index == 0 {
            self.index = self.menu_sub_index - 1;
        } else {
            self.index -= 1;
        }
    }
}

//创建开始菜单UI
fn spawn_start_menu_ui(mut commands: Commands, asset_server: Res<AssetServer>) {
    let font = asset_server.load("fonts/fusion-pixel.ttf");
    let start_menu_ui_text = StartMenuUIText {
        index: 0,
        menu_sub_index: 2,
    };
    commands
        .spawn((
            Node {
                width: Val::Percent(100.0),
                height: Val::Percent(100.0),
                align_items: AlignItems::Center,
                justify_content: JustifyContent::Center,
                ..default()
            },
            StartMenuUI,
        ))
        .with_children(|parent| {
            parent
                .spawn((
                    Node {
                        flex_direction: FlexDirection::Column,
                        align_items: AlignItems::Center,
                        ..default()
                    },
                    BackgroundColor(CRIMSON.into()),
                ))
                .with_children(|parent| {
                    parent
                        .spawn((
                            Text::new("上下键选择,空格或回车确认\n"),
                            TextFont {
                                font: font.clone(),
                                font_size: 25.0,
                                ..default()
                            },
                            Node {
                                margin: UiRect::all(Val::Px(50.0)),
                                ..default()
                            },
                            TextLayout::new_with_justify(JustifyText::Center),
                            start_menu_ui_text,
                        ))
                        .with_children(|parent| {
                            parent.spawn((
                                TextSpan::new("=>开始游戏<=\n"),
                                TextFont {
                                    font: font.clone(),
                                    font_size: 60.0,
                                    ..default()
                                },
                                TextColor(DARK_BLUE.into()),
                            ));
                            parent.spawn((
                                TextSpan::new("退出游戏"),
                                TextFont {
                                    font: font.clone(),
                                    font_size: 60.0,
                                    ..default()
                                },
                                TextColor(DARK_BLUE.into()),
                            ));
                        });
                });
        });
}

///卸载开始菜单UI
fn despawn_start_menu_ui(mut commands: Commands, query: Query<Entity, With<StartMenuUI>>) {
    for entity in query.iter() {
        commands.entity(entity).despawn();
    }
}

fn btn_click(
    keyboard_input: Res<ButtonInput<KeyCode>>,
    mut query: Single<&mut StartMenuUIText>,
    mut commands: Commands,
) {
    if keyboard_input.just_released(KeyCode::Space) {
        commands.trigger(ESpaceAndEnterClick);
    }
    if keyboard_input.just_released(KeyCode::Enter) {
        commands.trigger(ESpaceAndEnterClick);
    }
    if keyboard_input.just_released(KeyCode::ArrowUp) {
        query.up_indxe();
    }
    if keyboard_input.just_released(KeyCode::ArrowDown) {
        query.down_indxe();
    }
}

fn space_and_enter_event_obs(
    _: Trigger<ESpaceAndEnterClick>,
    mut commands: Commands,
    mut game_state: ResMut<NextState<GameState>>,
    curr_game_state: Res<State<GameState>>,
    mut app_exit_events: EventWriter<AppExit>,
    query: Single<&StartMenuUIText>,
) {
    match query.index {
        0 => {
            game_state.set(GameState::LevelLoading);
        }
        1 => {
            if *curr_game_state.get() == GameState::Pause {
                commands.trigger(ESaveGame);
            }
            app_exit_events.write(AppExit::Success);
        }
        _ => {}
    }
}

fn updata_start_ui(
    query: Single<(Entity, &mut StartMenuUIText)>,
    mut text_writer: TextUiWriter,
    game_state: Res<State<GameState>>,
) {
    let str = match game_state.get() {
        GameState::MainMenu => "开始游戏",
        GameState::Pause => "继续游戏",
        _ => "",
    };
    match query.1.index {
        0 => {
            *text_writer.text(query.0, 1) = format!("=>{}<=\n", str);
            *text_writer.text(query.0, 2) = "退出游戏\n".to_string();
        }
        1 => {
            *text_writer.text(query.0, 1) = format!("{}\n", str);
            *text_writer.text(query.0, 2) = "=>退出游戏<=\n".to_string();
        }
        _ => {}
    }
}

fn pause_game(
    keyboard_input: Res<ButtonInput<KeyCode>>,
    cur_state: Res<State<GameState>>,
    mut game_state: ResMut<NextState<GameState>>,
) {
    if keyboard_input.just_released(KeyCode::Escape) {
        match cur_state.get() {
            GameState::LevelLoading => {
                game_state.set(GameState::Pause);
            }
            GameState::Pause => {
                game_state.set(GameState::LevelLoading);
            }
            _ => {}
        }
    }
}

///游戏状态
#[derive(Clone, Copy, Default, Eq, PartialEq, Debug, Hash, States)]
pub enum GameState {
    #[default]
    //开始菜单,
    MainMenu,
    //游戏中,
    LevelLoading,
    //暂停,
    Pause,
}

/// 拦截窗口关闭事件
fn intercept_close_event(
    curr_game_state: Res<State<GameState>>,
    mut close_events: EventReader<WindowCloseRequested>,
    mut game_state: ResMut<NextState<GameState>>,
    mut app_exit_events: EventWriter<AppExit>,
) {
    for _ in close_events.read() {
        match curr_game_state.get() {
            GameState::MainMenu => {
                app_exit_events.write(AppExit::Success);
            }
            GameState::LevelLoading => {
                game_state.set(GameState::Pause);
            }
            _ => {}
        }
    }
}
